JavaScript-da 'for await...of' sikli va maxsus asinxron iterator yordamchilari yordamida asinxron iteratsiyani o'zlashtiring. Amaliy misollar bilan oqimlarni qayta ishlash va ma'lumotlar bilan ishlashni yaxshilang.
JavaScript Asinxron Iterator Yordamchisi: Har Biri Uchun - Oqimlarni Qayta Ishlash Iteratsiyasi
Asinxron dasturlash zamonaviy JavaScript ishlab chiqishining asosiy tamal toshidir, u ilovalarga asosiy oqimni bloklamasdan vaqt talab qiladigan operatsiyalarni bajarish imkonini beradi. ECMAScript 2018 da taqdim etilgan asinxron iteratorlar ma'lumotlar oqimlarini asinxron ravishda qayta ishlash uchun kuchli mexanizmni taqdim etadi. Ushbu blog posti asinxron iteratorlar tushunchasini chuqur o'rganadi va oqimlarni qayta ishlashni soddalashtirish uchun asinxron 'for each' yordamchi funksiyasini qanday amalga oshirishni ko'rsatadi.
Asinxron Iteratorlarni Tushunish
Asinxron iterator - bu AsyncIterator interfeysiga mos keladigan ob'ekt. U ikkita xususiyatga ega ob'ektga hal qilinadigan promissni qaytaradigan next() usulini belgilaydi:
value: Ketma-ketlikdagi keyingi qiymat.done: Iterator tugallanganligini ko'rsatuvchi mantiqiy qiymat.
Asinxron iteratorlar odatda tarmoq oqimlari, fayl tizimlari yoki ma'lumotlar bazalari kabi asinxron manbalardan ma'lumotlarni olish uchun ishlatiladi. for await...of sikli asinxron iteratsiyalanuvchilar ustida iteratsiya qilish uchun qulay sintaksisni taqdim etadi.
Misol: Fayldan Asinxron Ravishda O'qish
Asosiy oqimni bloklamasdan katta faylni satr-ma-satr o'qishingiz kerak bo'lgan stsenariyni ko'rib chiqing. Bunga asinxron iterator yordamida erishishingiz mumkin:
const fs = require('fs');
const readline = require('readline');
async function* readFileLines(filePath) {
const fileStream = fs.createReadStream(filePath);
const rl = readline.createInterface({
input: fileStream,
crlfDelay: Infinity
});
for await (const line of rl) {
yield line;
}
}
async function processFile(filePath) {
for await (const line of readFileLines(filePath)) {
console.log(`Line: ${line}`);
}
}
// Foydalanish misoli
processFile('path/to/your/file.txt');
Ushbu misolda, readFileLines - fayl o'qilishi bilan uning har bir satrini beradigan asinxron generator funksiyasi. Keyin processFile funksiyasi for await...of yordamida satrlar bo'ylab iteratsiya qilib, har bir satrni asinxron ravishda qayta ishlaydi.
Asinxron 'For Each' Yordamchisini Amalga Oshirish
for await...of sikli foydali bo'lsa-da, oqimdagi har bir element ustida murakkab operatsiyalarni bajarish kerak bo'lganda, u ancha uzun bo'lib ketishi mumkin. Asinxron 'for each' yordamchi funksiyasi iteratsiya mantiqini inkapsulyatsiya qilish orqali bu jarayonni soddalashtirishi mumkin.
Asosiy Amalga Oshirish
Quyida asinxron 'for each' funksiyasining asosiy amalga oshirilishi keltirilgan:
async function asyncForEach(iterable, callback) {
for await (const item of iterable) {
await callback(item);
}
}
Bu funksiya argument sifatida asinxron iteratsiyalanuvchi va callback funksiyasini qabul qiladi. U for await...of yordamida iteratsiyalanuvchi ustidan iteratsiya qiladi va har bir element uchun callback funksiyasini chaqiradi. Agar keyingi elementga o'tishdan oldin uning bajarilishini kutmoqchi bo'lsangiz, callback funksiyasi ham asinxron bo'lishi kerak.
Misol: API'dan Ma'lumotlarni Qayta Ishlash
Aytaylik, siz elementlar oqimini qaytaradigan API'dan ma'lumotlarni olayapsiz. Siz har bir elementni kelishi bilan qayta ishlash uchun asinxron 'for each' yordamchisidan foydalanishingiz mumkin:
async function* fetchDataStream(url) {
const response = await fetch(url);
const reader = response.body.getReader();
const decoder = new TextDecoder();
try {
while (true) {
const { done, value } = await reader.read();
if (done) {
return;
}
// API JSON qismlarini qaytaradi deb faraz qilamiz
const chunk = decoder.decode(value);
const items = JSON.parse(`[${chunk.replace(/\}\{/g, '},{')}]`); // Qismlarni yaroqli JSON massiviga ajratish
for(const item of items){
yield item;
}
}
} finally {
reader.releaseLock();
}
}
async function processItem(item) {
// Asinxron operatsiyani simulyatsiya qilish
await new Promise(resolve => setTimeout(resolve, 100));
console.log(`Processing item: ${JSON.stringify(item)}`);
}
async function main() {
const apiUrl = 'https://api.example.com/data'; // O'zingizning API manzilingiz bilan almashtiring
await asyncForEach(fetchDataStream(apiUrl), processItem);
console.log('Finished processing data.');
}
// Foydalanish misoli
main();
Ushbu misolda, fetchDataStream API'dan ma'lumotlarni oladi va har bir elementni qabul qilingan zahoti beradi. processItem funksiyasi har bir element ustida asinxron operatsiyani simulyatsiya qiladi. Keyin asyncForEach yordamchisi iteratsiya va qayta ishlash mantiqini soddalashtiradi.
Takomillashtirish va E'tiborga Olinadigan Jihatlar
Xatoliklarga Ishlov Berish
Asinxron iteratsiya paytida yuzaga kelishi mumkin bo'lgan xatoliklarga ishlov berish juda muhim. Xatoliklarni ushlash va ularga ishlov berish uchun callback funksiyasini try...catch bloki bilan o'rashingiz mumkin:
async function asyncForEach(iterable, callback) {
for await (const item of iterable) {
try {
await callback(item);
} catch (error) {
console.error(`Error processing item: ${item}`, error);
// Xatoni qayta yuborishni yoki qayta ishlashni davom ettirishni tanlashingiz mumkin
}
}
}
Parallel Bajarishni Boshqarish
Odatiy bo'lib, asinxron 'for each' yordamchisi elementlarni ketma-ket qayta ishlaydi. Agar siz elementlarni parallel ravishda qayta ishlashingiz kerak bo'lsa, parallel operatsiyalar sonini cheklash uchun Promise pulidan foydalanishingiz mumkin:
async function asyncForEachConcurrent(iterable, callback, concurrency) {
const executing = [];
for await (const item of iterable) {
const p = callback(item).then(() => executing.splice(executing.indexOf(p), 1));
executing.push(p);
if (executing.length >= concurrency) {
await Promise.race(executing);
}
}
await Promise.all(executing);
}
async function processItem(item) {
// Asinxron operatsiyani simulyatsiya qilish
await new Promise(resolve => setTimeout(resolve, 100));
console.log(`Processing item: ${JSON.stringify(item)}`);
}
async function main() {
const apiUrl = 'https://api.example.com/data'; // O'zingizning API manzilingiz bilan almashtiring
await asyncForEachConcurrent(fetchDataStream(apiUrl), processItem, 5); // Parallel bajarish darajasi 5
console.log('Finished processing data.');
}
Ushbu misolda, asyncForEachConcurrent parallel callback bajarilishlari sonini belgilangan parallel bajarish darajasi bilan cheklaydi. Bu katta ma'lumotlar oqimlari bilan ishlaganda samaradorlikni oshirishi mumkin.
Bekor Qilish
Ba'zi hollarda, iteratsiya jarayonini muddatidan oldin bekor qilishingiz kerak bo'lishi mumkin. Bunga AbortController yordamida erishishingiz mumkin:
async function asyncForEach(iterable, callback, signal) {
for await (const item of iterable) {
if (signal && signal.aborted) {
console.log('Iteration aborted.');
return;
}
await callback(item);
}
}
async function main() {
const controller = new AbortController();
const signal = controller.signal;
setTimeout(() => {
controller.abort(); // 2 soniyadan keyin bekor qilish
}, 2000);
const apiUrl = 'https://api.example.com/data'; // O'zingizning API manzilingiz bilan almashtiring
await asyncForEach(fetchDataStream(apiUrl), processItem, signal);
console.log('Finished processing data.');
}
Ushbu misolda, asyncForEach funksiyasi har bir iteratsiyadan oldin signal.aborted xususiyatini tekshiradi. Agar signal bekor qilingan bo'lsa, iteratsiya to'xtatiladi.
Haqiqiy Hayotdagi Qo'llanilishlar
Asinxron iteratorlar va asinxron 'for each' yordamchisi ko'plab real hayotiy stsenariylarda qo'llanilishi mumkin:
- Ma'lumotlarni qayta ishlash konveyerlari: Ma'lumotlar bazalari yoki fayl tizimlaridan katta ma'lumotlar to'plamlarini qayta ishlash.
- Real vaqtdagi ma'lumotlar oqimlari: Veb-soketlar, xabarlar navbatlari yoki sensor tarmoqlaridan ma'lumotlarga ishlov berish.
- API iste'moli: Elementlar oqimini qaytaradigan API'lardan ma'lumotlarni olish va qayta ishlash.
- Rasm va videolarni qayta ishlash: Katta media fayllarni qismlarga bo'lib qayta ishlash.
- Log tahlili: Katta log fayllarni satr-ma-satr tahlil qilish.
Misol - Xalqaro Birja Ma'lumotlari: Turli xalqaro birjalardan real vaqtdagi aksiya kotirovkalarini oladigan ilovani ko'rib chiqing. Asinxron iterator ma'lumotlarni oqimlash uchun ishlatilishi mumkin, va asinxron 'for each' har bir kotirovkani qayta ishlashi, foydalanuvchi interfeysini eng so'nggi narxlar bilan yangilashi mumkin. Bu quyidagi kompaniyalarning hozirgi aksiya narxlarini ko'rsatish uchun ishlatilishi mumkin:
- Tencent (Xitoy): Yirik xalqaro texnologiya kompaniyasining birja ma'lumotlarini olish
- Tata Consultancy Services (Hindiston): Yetakchi IT xizmatlari kompaniyasidan birja yangilanishlarini ko'rsatish
- Samsung Electronics (Janubiy Koreya): Global elektronika ishlab chiqaruvchisidan birja narxlarini namoyish etish
- Toyota Motor Corporation (Yaponiya): Xalqaro avtomobil ishlab chiqaruvchisining aksiya narxlarini kuzatish
Xulosa
Asinxron iteratorlar va asinxron 'for each' yordamchisi JavaScript-da ma'lumotlar oqimlarini asinxron ravishda qayta ishlashning kuchli va nafis usulini taqdim etadi. Iteratsiya mantiqini inkapsulyatsiya qilish orqali siz kodingizni soddalashtirishingiz, o'qiluvchanligini yaxshilashingiz va ilovalaringizning samaradorligini oshirishingiz mumkin. Xatoliklarga ishlov berish, parallel bajarishni boshqarish va bekor qilish imkoniyatini yaratish orqali siz mustahkam va kengaytiriladigan asinxron ma'lumotlarni qayta ishlash konveyerlarini yaratishingiz mumkin.